home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / xvisrc.zip / IBMPC_C.C < prev    next >
C/C++ Source or Header  |  1992-07-28  |  6KB  |  275 lines

  1. /* Copyright (c) 1990,1991,1992 Chris and John Downey */
  2. #ifndef lint
  3. static char *sccsid = "@(#)ibmpc_c.c    2.1 (Chris & John Downey) 7/29/92";
  4. #endif
  5.  
  6. /***
  7.  
  8. * program name:
  9.     xvi
  10. * function:
  11.     PD version of UNIX "vi" editor, with extensions.
  12. * module name:
  13.     ibmpc_c.c
  14. * module function:
  15.     C part of terminal interface module for IBM PC compatibles
  16.     running MS-DOS.
  17.  
  18. * history:
  19.     STEVIE - ST Editor for VI Enthusiasts, Version 3.10
  20.     Originally by Tim Thompson (twitch!tjt)
  21.     Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
  22.     Heavily modified by Chris & John Downey
  23.  
  24. ***/
  25.  
  26. #include "xvi.h"
  27.  
  28. /*
  29.  * Screen dimensions, defined here so they'll go in the C default data
  30.  * segment.
  31.  */
  32. unsigned int    Rows;
  33. unsigned int    Columns;
  34.  
  35. /*
  36.  * IBM-compatible PC's have a default typeahead buffer which is only
  37.  * big enough for 16 characters, & some 8088-based PC's are so
  38.  * unbelievably slow that xvi can't handle more than about 2
  39.  * characters a second. So we do some input buffering here to
  40.  * alleviate the problem.
  41.  */
  42.  
  43. static    char        kbuf[16];
  44. static    char        *kbrp = kbuf;
  45. static    char        *kbwp = kbuf;
  46. static    unsigned    kbcount;
  47.  
  48. static void near
  49. kbfill()
  50. {
  51.     register int    c;
  52.  
  53.     while (kbcount < sizeof kbuf && (c = getchnw()) >= 0) {
  54.     kbcount++;
  55.     *kbwp = c;
  56.     if (kbwp++ >= &kbuf[sizeof kbuf - 1])
  57.         kbwp = kbuf;
  58.     }
  59. }
  60.  
  61. static unsigned char near
  62. kbget()
  63. {
  64.     for (;;) {
  65.     if (kbcount > 0) {
  66.         unsigned char c;
  67.  
  68.         --kbcount;
  69.         c = *kbrp;
  70.         if (kbrp++ >= &kbuf[sizeof kbuf - 1])
  71.         kbrp = kbuf;
  72.         return c;
  73.     } else {
  74.         kbfill();
  75.     }
  76.     }
  77. }
  78.  
  79. /*
  80.  * Convert milliseconds to clock ticks.
  81.  */
  82. #if CLK_TCK > 1000
  83. #        define    MS2CLK(m)    ((long)(m) * (CLK_TCK / 1000))
  84. #else
  85. #    if CLK_TCK < 1000
  86. #        define    MS2CLK(m)    ((long)(m) / (1000 / CLK_TCK))
  87. #    else
  88. #        define    MS2CLK(m)    (m)
  89. #    endif
  90. #endif
  91.  
  92. /*
  93.  * inchar() - get a character from the keyboard
  94.  */
  95. int
  96. inchar(long mstimeout)
  97. {
  98.     clock_t        stoptime;
  99.  
  100.     if (kbcount == 0) {
  101.     flush_output();
  102.     if (mstimeout != 0) {
  103.         stoptime = clock() + MS2CLK(mstimeout);
  104.     }
  105.     kbfill();
  106.     }
  107.     for (;;) {
  108.     static clock_t    lastevent;
  109.     register int    c;
  110.  
  111.     if (kbcount == 0) {
  112.         unsigned    prevbstate;
  113.         unsigned    prevx, prevy;
  114.         bool_t    isdrag;
  115.  
  116.         if (State == NORMAL) {
  117.         showmouse();
  118.         prevbstate = 0;
  119.         }
  120.         for (; kbcount == 0; kbfill()) {
  121.         /*
  122.          * Time out if we have to.
  123.          */
  124.         if (mstimeout != 0 && clock() > stoptime) {
  125.             break;
  126.         }
  127.         if (State == NORMAL) {
  128.             unsigned    buttonstate;
  129.             unsigned    mousex,
  130.                 mousey;
  131.  
  132.             /*
  133.              * If there's no keyboard input waiting to be
  134.              * read, watch out for mouse events. We don't do
  135.              * this if we're in insert or command line mode.
  136.              */
  137.  
  138.             buttonstate = mousestatus(&mousex, &mousey) & 7;
  139.             mousex /= 8;
  140.             mousey /= 8;
  141.             if (prevbstate == 0) {
  142.             isdrag = FALSE;
  143.             } else {
  144.             if (buttonstate) {
  145.                 /*
  146.                  * If a button is being held down, & the
  147.                  * position has changed, this is a mouse
  148.                  * drag event.
  149.                  */
  150.                 if (mousex != prevx || mousey != prevy) {
  151.                 hidemouse();
  152.                 mousedrag(prevy, mousey, prevx, mousex);
  153.                 showmouse();
  154.                 isdrag = TRUE;
  155.                 }
  156.             } else {
  157.                 if (!isdrag) {
  158.                 /*
  159.                  * They've pressed & released a button
  160.                  * without moving the mouse.
  161.                  */
  162.                 hidemouse();
  163.                 mouseclick(mousey, mousex);
  164.                 showmouse();
  165.                 }
  166.             }
  167.             }
  168.             if ((prevbstate = buttonstate) != 0) {
  169.             prevx = mousex;
  170.             prevy = mousey;
  171.             }
  172.         }
  173.         }
  174.         if (State == NORMAL) {
  175.         hidemouse();
  176.         }
  177.         if (kbcount == 0) {
  178.         /*
  179.          * We must have timed out.
  180.          */
  181.         return EOF;
  182.         }
  183.     }
  184.     c = kbget();
  185.     /*
  186.      * On IBM compatible PC's, function keys return '\0' followed
  187.      * by another character. Check for this, and turn function key
  188.      * presses into appropriate "normal" characters to do the
  189.      * right thing in xvi.
  190.      */
  191.     if (c != '\0') {
  192.         return(c);
  193.     }
  194.     /* else must be a function key press */
  195.     {
  196.         if (State != NORMAL) {
  197.         /*
  198.          * Function key pressed during insert or command line
  199.          * mode. Get the next character ...
  200.          */
  201.         if (kbget() == 0x53) {
  202.             /*
  203.              * ... and if it's the delete key, return it as a
  204.              * backspace ...
  205.              */
  206.             return '\b';
  207.         }
  208.         /*
  209.          * ... otherwise it isn't valid ...
  210.          */
  211.         alert();
  212.  
  213.         /*
  214.          * Typical MS-DOS users are fairly naive & may not
  215.          * understand how to get out of insert mode. To make
  216.          * things easier, we do it for them here.
  217.          */
  218.         switch (State) {
  219.         case INSERT:
  220.         case REPLACE:
  221.             return ESC;
  222.         default:
  223.             continue;
  224.         }
  225.         }
  226.         /* else (State == NORMAL) ... */
  227.         switch (kbget()) {
  228.         case 0x3b: return(K_HELP);        /* F1 key */
  229.         case 0x47: return('H');        /* home key */
  230.         case 0x48: return('k');        /* up arrow key */
  231.         case 0x49: return (CTRL('B'));    /* page up key */
  232.         case 0x4b: return('\b');        /* left arrow key */
  233.         case 0x4d: return(' ');        /* right arrow key */
  234.         case 0x4f: return('L');        /* end key */
  235.         case 0x50: return('j');        /* down arrow key */
  236.         case 0x51: return (CTRL('F'));    /* page down key */
  237.         case 0x52: return('i');        /* insert key */
  238.         case 0x53: return('x');        /* delete key */
  239.         /*
  240.          * default:
  241.          *    fall through and ignore both characters ...
  242.          */
  243.         }
  244.         continue;
  245.     }
  246.     }
  247. }
  248.  
  249. #ifdef __ZTC__
  250. #   ifdef DOS386
  251. #    define Z386
  252. #   endif
  253. #endif
  254.  
  255. #ifndef Z386
  256.  
  257. /*
  258.  * The routines in ibmpc_a.asm need to call this because they can't
  259.  * invoke C macros directly.
  260.  *
  261.  * Return Pn(P_colour) in the al register, Pn(P_statuscolour) in ah, &
  262.  * Pb(P_vbell) in dx.
  263.  *
  264.  * This will only work with a Microsoft-compatible compiler.
  265.  */
  266. long
  267. cparams()
  268. {
  269.     return ((long) Pb(P_vbell) << 16) |
  270.        (unsigned short) ((Pn(P_statuscolour) << 8) |
  271.          (unsigned char) Pn(P_colour));
  272. }
  273.  
  274. #endif    /* not Z386 */
  275.